package com.denghq.projectbuilder.component.consul.config.configuration;

import com.denghq.projectbuilder.component.config.domain.ConfigClassCollector;
import com.denghq.projectbuilder.component.config.domain.ConfigClassParser;
import com.ecwid.consul.v1.ConsulClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.consul.ConditionalOnConsulEnabled;
import org.springframework.cloud.consul.ConsulAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@ConditionalOnConsulEnabled
public class ConsulConfigBootstrapConfiguration {
    public ConsulConfigBootstrapConfiguration() {
    }

    @Configuration
    @EnableConfigurationProperties
    @Import({ConsulAutoConfiguration.class})
    @ConditionalOnProperty(
            name = {"spring.cloud.consul.config.enabled"},
            matchIfMissing = true
    )
    /**
     * 配置自动注册器,用于自动向consul注册配置
     */
    protected static class ConfigAutoRegisterConfiguration {

        @Autowired
        private ConsulClient consul;

        @Value("${spring.application.name}")
        private String appNo;

        protected ConfigAutoRegisterConfiguration() {
        }

        @Bean
        @ConditionalOnMissingBean(ConsulConfigProperties.class)
        public ConsulConfigProperties configProperties() {
            return new ConsulConfigProperties();
        }

        /**
         * 配置类收集器
         *
         * @param configProperties
         * @return
         */
        @Bean
        @ConditionalOnMissingBean(ConfigClassCollector.class)
        public ConfigClassCollector consulConfigClassCollector(ConsulConfigProperties configProperties) {
            return StringUtils.isBlank(configProperties.getBasePackage()) ?
                    new ConfigClassCollector() : new ConfigClassCollector(configProperties.getBasePackage());
        }

        /**
         * 配置类解析器
         *
         * @param consulConfigClassCollector
         * @return
         */
        @Bean
        @ConditionalOnMissingBean(ConfigClassParser.class)
        public ConfigClassParser consulConfigClassParser(ConfigClassCollector consulConfigClassCollector) {
            return new ConfigClassParser(consulConfigClassCollector.getConfigClasses(), appNo);
        }

        /**
         * 配置类注册器
         *
         * @param consulConfigClassParser
         * @param configProperties
         * @return
         */
        @Bean
        @ConditionalOnMissingBean(ConsulConfigAutoRegister.class)
        public ConsulConfigAutoRegister consulConfigAutoRegister(ConfigClassParser consulConfigClassParser, ConsulConfigProperties configProperties) {
            ConsulConfigAutoRegister consulConfigAutoRegister = new ConsulConfigAutoRegister(this.consul, consulConfigClassParser.getConfigDescriptorListList(), configProperties, appNo);
            consulConfigAutoRegister.registe();
            return consulConfigAutoRegister;
        }

        /**
         * 配置类管理器
         *
         * @param consulConfigClassParser
         * @param consulConfigAutoRegister
         * @return
         */
        @Bean
        @ConditionalOnMissingBean(ConsulConfigManager.class)
        public ConsulConfigManager consulConfigManager(ConfigClassParser consulConfigClassParser, ConsulConfigAutoRegister consulConfigAutoRegister) {
            return new ConsulConfigManager(consulConfigClassParser, consulConfigAutoRegister);
        }

    }

    /**
     * 属性加载器（加载外部属性）
     */
    @Configuration
    @EnableConfigurationProperties
    @Import({ConsulAutoConfiguration.class})
    @ConditionalOnProperty(
            name = {"com.denghq.component.consul.config.enabled"},
            matchIfMissing = true
    )
    protected static class ConfigPropertySourceConfiguration {
        @Autowired
        private ConsulClient consul;

        protected ConfigPropertySourceConfiguration() {
        }


        @Bean
        @ConditionalOnMissingBean(ConsulConfigPropertySourceLocator.class)
        public ConsulConfigPropertySourceLocator consulPropertySourceLocator(ConfigClassParser consulConfigClassParser, ConsulConfigAutoRegister consulConfigAutoRegister, ConsulConfigProperties configProperties) {
            return new ConsulConfigPropertySourceLocator(this.consul, consulConfigClassParser.getConfigDescriptorListList(), consulConfigAutoRegister, configProperties);
        }
    }
}
